package net.lab1024.sa.base.module.support.elasticsearch.domain.kql;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * KQL查询解析器 - 将KQL查询语句转换为ES查询
 */
@Slf4j
public class KqlParser {

    /**
     * 解析KQL查询字符串为ES查询
     */
    public static JSONObject parseKqlToEsQuery(String kqlString) {
        if (StringUtils.isBlank(kqlString)) {
            return null;
        }

        try {
            // 标准化查询字符串
            String normalizedQuery = normalizeQuery(kqlString);
            log.debug("标准化查询: {}", normalizedQuery);

            // 解析查询
            return parseExpression(normalizedQuery);
        } catch (Exception e) {
            log.error("解析KQL查询失败:", e);
            return null;
        }
    }

    /**
     * 标准化查询字符串
     */
    private static String normalizeQuery(String query) {
        return query.trim()
                .replaceAll("\\s+", " ")
                .replaceAll("\\(\\s+", "(")
                .replaceAll("\\s+\\)", ")")
                .replaceAll("\\s*\\(\\s*", " ( ")
                .replaceAll("\\s*\\)\\s*", " ) ");
    }

    /**
     * 解析表达式
     */
    private static JSONObject parseExpression(String expr) {
        if (StringUtils.isBlank(expr)) {
            return null;
        }

        // 移除最外层的括号
        expr = removeOuterParentheses(expr);

        // 查找顶层的AND/OR操作符
        List<String> tokens = tokenize(expr);
        
        // 先处理AND操作符（优先级较高）
        int andIndex = findTopLevelOperator(tokens, "AND");
        if (andIndex >= 0) {
            // 分割左右表达式
            String leftExpr = joinTokens(tokens.subList(0, andIndex));
            String rightExpr = joinTokens(tokens.subList(andIndex + 1, tokens.size()));

            // 递归解析左右表达式
            JSONObject leftQuery = parseExpression(leftExpr);
            JSONObject rightQuery = parseExpression(rightExpr);

            if (leftQuery == null || rightQuery == null) {
                return null;
            }

            // 构建bool查询
            JSONObject bool = new JSONObject();
            bool.put("must", Arrays.asList(leftQuery, rightQuery));

            JSONObject query = new JSONObject();
            query.put("bool", bool);
            return query;
        }
        
        // 再处理OR操作符（优先级较低）
        int orIndex = findTopLevelOrOperator(tokens);
        if (orIndex >= 0) {
            // 分割左右表达式
            String leftExpr = joinTokens(tokens.subList(0, orIndex));
            String rightExpr = joinTokens(tokens.subList(orIndex + 1, tokens.size()));

            // 递归解析左右表达式
            JSONObject leftQuery = parseExpression(leftExpr);
            JSONObject rightQuery = parseExpression(rightExpr);

            if (leftQuery == null || rightQuery == null) {
                return null;
            }

            // 构建bool查询
            JSONObject bool = new JSONObject();
            bool.put("should", Arrays.asList(leftQuery, rightQuery));
            bool.put("minimum_should_match", 1);

            JSONObject query = new JSONObject();
            query.put("bool", bool);
            return query;
        }

        // 没有AND/OR操作符，解析单个条件
        return parseCondition(expr);
    }

    /**
     * 移除最外层的括号
     */
    private static String removeOuterParentheses(String expr) {
        expr = expr.trim();
        while (expr.startsWith("(") && expr.endsWith(")")) {
            // 检查是否是匹配的括号
            int count = 0;
            boolean isMatching = true;
            for (int i = 0; i < expr.length(); i++) {
                if (expr.charAt(i) == '(') count++;
                if (expr.charAt(i) == ')') count--;
                if (count == 0 && i < expr.length() - 1) {
                    isMatching = false;
                    break;
                }
            }
            if (!isMatching) break;
            expr = expr.substring(1, expr.length() - 1).trim();
        }
        return expr;
    }

    /**
     * 将表达式分割为token
     */
    private static List<String> tokenize(String expr) {
        List<String> tokens = new ArrayList<>();
        StringBuilder current = new StringBuilder();
        int parentheses = 0;
        boolean inQuotes = false;
        char quoteChar = 0;

        for (int i = 0; i < expr.length(); i++) {
            char c = expr.charAt(i);

            if ((c == '"' || c == '\'') && (i == 0 || expr.charAt(i - 1) != '\\')) {
                if (!inQuotes) {
                    inQuotes = true;
                    quoteChar = c;
                } else if (c == quoteChar) {
                    inQuotes = false;
                }
            }

            if (!inQuotes) {
                if (c == '(') {
                    parentheses++;
                } else if (c == ')') {
                    parentheses--;
                }
            }

            if (!inQuotes && parentheses == 0 && c == ' ') {
                if (current.length() > 0) {
                    tokens.add(current.toString());
                    current = new StringBuilder();
                }
            } else {
                current.append(c);
            }
        }

        if (current.length() > 0) {
            tokens.add(current.toString());
        }

        return tokens;
    }

    /**
     * 查找顶层操作符（从右到左查找，确保正确的结合性）
     */
    private static int findTopLevelOperator(List<String> tokens, String operator) {
        int parentheses = 0;
        for (int i = tokens.size() - 1; i >= 0; i--) {
            String token = tokens.get(i);
            if (")".equals(token)) {
                parentheses++;
            } else if ("(".equals(token)) {
                parentheses--;
            } else if (parentheses == 0 && token.equalsIgnoreCase(operator)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 查找顶层OR操作符（从左到右查找第一个，确保在同一括号层级）
     */
    private static int findTopLevelOrOperator(List<String> tokens) {
        int parentheses = 0;
        for (int i = 0; i < tokens.size(); i++) {
            String token = tokens.get(i);
            if ("(".equals(token)) {
                parentheses++;
            } else if (")".equals(token)) {
                parentheses--;
            } else if (parentheses == 0 && token.equalsIgnoreCase("OR")) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 将token列表合并为字符串
     */
    private static String joinTokens(List<String> tokens) {
        return String.join(" ", tokens);
    }

    /**
     * 解析单个条件
     */
    private static JSONObject parseCondition(String expr) {
        try {
            log.debug("解析条件: {}", expr);

            // 操作符模式
            String operatorPattern = "not\\s+contains|contains|not\\s+in|in|==|!=|>=|<=|>|<|:|\\*|exists|not\\s+exists";
            Pattern pattern = Pattern.compile("^([\\w\\._-]+)\\s*(" + operatorPattern + ")\\s*(.+)?$");
            Matcher matcher = pattern.matcher(expr);

            if (!matcher.matches()) {
                log.debug("条件不匹配正则: {}", expr);
                return null;
            }

            String field = matcher.group(1);
            String operator = matcher.group(2);
            String value = matcher.group(3);
            String cleanValue = value != null ? value.trim() : "";

            // 去除外层引号
            if ((cleanValue.startsWith("\"") && cleanValue.endsWith("\"")) ||
                    (cleanValue.startsWith("'") && cleanValue.endsWith("'"))) {
                cleanValue = cleanValue.substring(1, cleanValue.length() - 1);
            }

            // 处理数组值
            List<String> arrayValue = null;
            if ((cleanValue.startsWith("[") && cleanValue.endsWith("]")) ||
                    (operator.contains("in"))) {
                try {
                    if (cleanValue.startsWith("[") && cleanValue.endsWith("]")) {
                        String arrayStr = cleanValue.substring(1, cleanValue.length() - 1);
                        arrayValue = Arrays.stream(arrayStr.split(","))
                                .map(String::trim)
                                .map(val -> {
                                    if ((val.startsWith("\"") && val.endsWith("\"")) ||
                                            (val.startsWith("'") && val.endsWith("'"))) {
                                        return val.substring(1, val.length() - 1);
                                    }
                                    return val;
                                })
                                .collect(Collectors.toList());
                    } else {
                        arrayValue = Collections.singletonList(cleanValue);
                    }
                } catch (Exception e) {
                    log.error("解析数组值失败:", e);
                    return null;
                }
            }

            log.debug("解析结果: field={}, operator={}, cleanValue={}", field, operator, cleanValue);

            JSONObject query = new JSONObject();
            switch (operator.toLowerCase()) {
                case ":":
                case "==":
                    JSONObject matchPhrase = new JSONObject();
                    matchPhrase.put(field, cleanValue);
                    query.put("match_phrase", matchPhrase);
                    break;

                case "*":
                    JSONObject wildcard = new JSONObject();
                    wildcard.put(field, "*" + cleanValue + "*");
                    query.put("wildcard", wildcard);
                    break;

                case "!=":
                    JSONObject notMatchPhrase = new JSONObject();
                    notMatchPhrase.put(field, cleanValue);
                    JSONObject notBool = new JSONObject();
                    notBool.put("must_not", Collections.singletonList(Collections.singletonMap("match_phrase", notMatchPhrase)));
                    query.put("bool", notBool);
                    break;

                case ">":
                    JSONObject gtRange = new JSONObject();
                    gtRange.put(field, Collections.singletonMap("gt", cleanValue));
                    query.put("range", gtRange);
                    break;

                case ">=":
                    JSONObject gteRange = new JSONObject();
                    gteRange.put(field, Collections.singletonMap("gte", cleanValue));
                    query.put("range", gteRange);
                    break;

                case "<":
                    JSONObject ltRange = new JSONObject();
                    ltRange.put(field, Collections.singletonMap("lt", cleanValue));
                    query.put("range", ltRange);
                    break;

                case "<=":
                    JSONObject lteRange = new JSONObject();
                    lteRange.put(field, Collections.singletonMap("lte", cleanValue));
                    query.put("range", lteRange);
                    break;

                case "contains":
                    JSONObject contains = new JSONObject();
                    contains.put(field, "*" + cleanValue + "*");
                    query.put("wildcard", contains);
                    break;

                case "not contains":
                    JSONObject notContainsWildcard = new JSONObject();
                    notContainsWildcard.put(field, "*" + cleanValue + "*");
                    JSONObject notContainsBool = new JSONObject();
                    notContainsBool.put("must_not", Collections.singletonList(Collections.singletonMap("wildcard", notContainsWildcard)));
                    query.put("bool", notContainsBool);
                    break;

                case "in":
                    JSONObject terms = new JSONObject();
                    terms.put(field, arrayValue != null ? arrayValue : Collections.singletonList(cleanValue));
                    query.put("terms", terms);
                    break;

                case "not in":
                    JSONObject notInTerms = new JSONObject();
                    notInTerms.put(field, arrayValue != null ? arrayValue : Collections.singletonList(cleanValue));
                    JSONObject notInBool = new JSONObject();
                    notInBool.put("must_not", Collections.singletonList(Collections.singletonMap("terms", notInTerms)));
                    query.put("bool", notInBool);
                    break;

                case "exists":
                    JSONObject exists = new JSONObject();
                    exists.put("field", field);
                    query.put("exists", exists);
                    break;

                case "not exists":
                    JSONObject notExistsExists = new JSONObject();
                    notExistsExists.put("field", field);
                    JSONObject notExistsBool = new JSONObject();
                    notExistsBool.put("must_not", Collections.singletonList(Collections.singletonMap("exists", notExistsExists)));
                    query.put("bool", notExistsBool);
                    break;

                default:
                    JSONObject match = new JSONObject();
                    match.put(field, cleanValue);
                    query.put("match", match);
                    break;
            }

            return query;
        } catch (Exception e) {
            log.error("解析单个条件失败:", e);
            return null;
        }
    }

    /**
     * 解析表达式结果
     */
    @Data
    private static class ParseResult {
        private JSONObject result;
        private int nextIndex;

        public ParseResult(JSONObject result, int nextIndex) {
            this.result = result;
            this.nextIndex = nextIndex;
        }
    }

    /**
     * 解析表达式
     */
    private static ParseResult parseExpression(List<String> tokens, int startIndex) {
        log.debug("开始解析表达式, tokens: {}", tokens.subList(startIndex, tokens.size()));

        List<ConditionItem> conditions = new ArrayList<>();
        StringBuilder currentCondition = new StringBuilder();
        int i = startIndex;
        String currentOperator = "AND";

        while (i < tokens.size()) {
            String token = tokens.get(i);
            log.debug("处理token: {}, 当前条件: {}", token, currentCondition);

            if ("(".equals(token)) {
                // 处理当前条件
                if (currentCondition.length() > 0) {
                    JSONObject parsed = parseCondition(currentCondition.toString().trim());
                    if (parsed != null) {
                        conditions.add(new ConditionItem(parsed, currentOperator));
                    }
                    currentCondition = new StringBuilder();
                }

                // 递归处理括号内的表达式
                ParseResult nestedResult = parseExpression(tokens, i + 1);
                if (nestedResult.getResult() != null) {
                    conditions.add(new ConditionItem(nestedResult.getResult(), currentOperator));
                }
                i = nestedResult.getNextIndex();
            } else if (")".equals(token)) {
                // 处理最后一个条件
                if (currentCondition.length() > 0) {
                    JSONObject parsed = parseCondition(currentCondition.toString().trim());
                    if (parsed != null) {
                        conditions.add(new ConditionItem(parsed, currentOperator));
                    }
                }
                return new ParseResult(buildNestedQuery(conditions), i + 1);
            } else if ("OR".equalsIgnoreCase(token) || "AND".equalsIgnoreCase(token)) {
                if (currentCondition.length() > 0) {
                    JSONObject parsed = parseCondition(currentCondition.toString().trim());
                    if (parsed != null) {
                        conditions.add(new ConditionItem(parsed, currentOperator));
                    }
                    currentCondition = new StringBuilder();
                }
                currentOperator = token.toUpperCase();
            } else {
                if (currentCondition.length() > 0) {
                    currentCondition.append(" ");
                }
                currentCondition.append(token);
            }
            i++;
        }

        // 处理最后一个条件
        if (currentCondition.length() > 0) {
            JSONObject parsed = parseCondition(currentCondition.toString().trim());
            if (parsed != null) {
                conditions.add(new ConditionItem(parsed, currentOperator));
            }
        }

        return new ParseResult(buildNestedQuery(conditions), i);
    }

    /**
     * 条件项
     */
    @Data
    private static class ConditionItem {
        private JSONObject condition;
        private String operator;

        public ConditionItem(JSONObject condition, String operator) {
            this.condition = condition;
            this.operator = operator;
        }
    }

    /**
     * 构建嵌套查询
     */
    private static JSONObject buildNestedQuery(List<ConditionItem> conditions) {
        if (conditions.isEmpty()) {
            return null;
        }
        if (conditions.size() == 1) {
            return conditions.get(0).getCondition();
        }

        JSONObject currentQuery = null;
        String currentOperator = null;

        for (int i = 0; i < conditions.size(); i++) {
            ConditionItem item = conditions.get(i);
            JSONObject condition = item.getCondition();
            String operator = item.getOperator();

            if (currentQuery == null) {
                currentQuery = condition;
                currentOperator = operator;
                continue;
            }

            if ("AND".equals(operator)) {
                JSONObject bool = new JSONObject();
                bool.put("must", Arrays.asList(currentQuery, condition));
                currentQuery = new JSONObject();
                currentQuery.put("bool", bool);
            } else { // OR
                JSONObject currentBool = currentQuery.getJSONObject("bool");
                if (currentBool != null && currentBool.containsKey("should")) {
                    // 如果已经是OR组合，添加到should数组
                    currentBool.getJSONArray("should").add(condition);
                } else {
                    // 创建新的OR组合
                    JSONObject bool = new JSONObject();
                    bool.put("should", Arrays.asList(currentQuery, condition));
                    bool.put("minimum_should_match", 1);
                    currentQuery = new JSONObject();
                    currentQuery.put("bool", bool);
                }
            }
        }

        return currentQuery;
    }

    /**
     * 将KQL查询转换为前端格式
     */
    public static Map<String, Object> toFrontEndQuery(String kqlString) {
        if (StringUtils.isBlank(kqlString)) {
            return new HashMap<>();
        }

        try {
            // 先转换为ES查询
            JSONObject esQuery = parseKqlToEsQuery(kqlString);
            if (esQuery == null) {
                return new HashMap<>();
            }

            // 将ES查询转换为前端格式
            return convertEsQueryToFrontend(esQuery);
        } catch (Exception e) {
            log.error("KQL转换前端格式失败:", e);
            return new HashMap<>();
        }
    }

    /**
     * 将ES查询转换为前端格式
     */
    private static Map<String, Object> convertEsQueryToFrontend(JSONObject esQuery) {
        Map<String, Object> frontendQuery = new HashMap<>();

        // 处理bool查询
        if (esQuery.containsKey("bool")) {
            JSONObject bool = esQuery.getJSONObject("bool");
            
            // 处理must (AND)
            if (bool.containsKey("must")) {
                List<Object> must = bool.getJSONArray("must");
                List<Map<String, Object>> andConditions = new ArrayList<>();
                for (Object condition : must) {
                    if (condition instanceof JSONObject) {
                        andConditions.add(convertSingleCondition((JSONObject) condition));
                    }
                }
                frontendQuery.put("and", andConditions);
            }
            
            // 处理should (OR)
            if (bool.containsKey("should")) {
                List<Object> should = bool.getJSONArray("should");
                List<Map<String, Object>> orConditions = new ArrayList<>();
                for (Object condition : should) {
                    if (condition instanceof JSONObject) {
                        orConditions.add(convertSingleCondition((JSONObject) condition));
                    }
                }
                frontendQuery.put("or", orConditions);
            }
            
            // 处理must_not (NOT)
            if (bool.containsKey("must_not")) {
                List<Object> mustNot = bool.getJSONArray("must_not");
                List<Map<String, Object>> notConditions = new ArrayList<>();
                for (Object condition : mustNot) {
                    if (condition instanceof JSONObject) {
                        notConditions.add(convertSingleCondition((JSONObject) condition));
                    }
                }
                frontendQuery.put("not", notConditions);
            }
        } else {
            // 单个条件
            frontendQuery = convertSingleCondition(esQuery);
        }

        return frontendQuery;
    }

    /**
     * 将前端查询对象转换为ES查询
     */
    public static JSONObject parseFrontendQuery(Object queryObj) {
        if (queryObj == null) {
            return null;
        }

        try {
            // 如果传入的是字符串，先转换为JSON对象
            JSONObject query;
            if (queryObj instanceof String) {
                query = JSON.parseObject((String) queryObj);
            } else if (queryObj instanceof Map) {
                query = new JSONObject((Map<String, Object>) queryObj);
            } else {
                query = (JSONObject) queryObj;
            }

            // 如果是空查询，返回null
            if (query == null || query.isEmpty()) {
                return null;
            }

            JSONObject esQuery = new JSONObject();
            JSONObject bool = new JSONObject();
            esQuery.put("bool", bool);

            // 处理AND条件
            if (query.containsKey("and")) {
                JSONArray andConditions = query.getJSONArray("and");
                if (andConditions != null && !andConditions.isEmpty()) {
                    List<JSONObject> mustClauses = new ArrayList<>();
                    for (int i = 0; i < andConditions.size(); i++) {
                        JSONObject condition = andConditions.getJSONObject(i);
                        if (isValidCondition(condition)) {
                            JSONObject esCondition = convertFrontendConditionToEs(condition);
                            if (esCondition != null) {
                                mustClauses.add(esCondition);
                            }
                        }
                    }
                    if (!mustClauses.isEmpty()) {
                        bool.put("must", mustClauses);
                    }
                }
            }

            // 处理OR条件
            if (query.containsKey("or")) {
                JSONArray orConditions = query.getJSONArray("or");
                if (orConditions != null && !orConditions.isEmpty()) {
                    List<JSONObject> shouldClauses = new ArrayList<>();
                    for (int i = 0; i < orConditions.size(); i++) {
                        JSONObject condition = orConditions.getJSONObject(i);
                        if (isValidCondition(condition)) {
                            JSONObject esCondition = convertFrontendConditionToEs(condition);
                            if (esCondition != null) {
                                shouldClauses.add(esCondition);
                            }
                        }
                    }
                    if (!shouldClauses.isEmpty()) {
                        bool.put("should", shouldClauses);
                        bool.put("minimum_should_match", 1);
                    }
                }
            }

            // 处理NOT条件
            if (query.containsKey("not")) {
                JSONArray notConditions = query.getJSONArray("not");
                if (notConditions != null && !notConditions.isEmpty()) {
                    List<JSONObject> mustNotClauses = new ArrayList<>();
                    for (int i = 0; i < notConditions.size(); i++) {
                        JSONObject condition = notConditions.getJSONObject(i);
                        if (isValidCondition(condition)) {
                            JSONObject esCondition = convertFrontendConditionToEs(condition);
                            if (esCondition != null) {
                                mustNotClauses.add(esCondition);
                            }
                        }
                    }
                    if (!mustNotClauses.isEmpty()) {
                        bool.put("must_not", mustNotClauses);
                    }
                }
            }

            // 如果没有任何有效的查询条件，返回null
            if (bool.isEmpty()) {
                return null;
            }

            // 如果只有一个条件，直接返回该条件
            if (bool.size() == 1) {
                if (bool.containsKey("must") && bool.getJSONArray("must").size() == 1) {
                    return bool.getJSONArray("must").getJSONObject(0);
                }
                if (bool.containsKey("should") && bool.getJSONArray("should").size() == 1) {
                    return bool.getJSONArray("should").getJSONObject(0);
                }
                if (bool.containsKey("must_not") && bool.getJSONArray("must_not").size() == 1) {
                    JSONObject notQuery = new JSONObject();
                    notQuery.put("bool", new JSONObject());
                    notQuery.getJSONObject("bool").put("must_not", 
                        Collections.singletonList(bool.getJSONArray("must_not").getJSONObject(0)));
                    return notQuery;
                }
            }

            return esQuery;
        } catch (Exception e) {
            log.error("解析前端查询对象失败:", e);
            return null;
        }
    }

    /**
     * 检查条件是否有效
     */
    private static boolean isValidCondition(JSONObject condition) {
        if (condition == null || condition.isEmpty()) {
            return false;
        }
        String field = condition.getString("field");
        String operator = condition.getString("operator");
        return StringUtils.isNotBlank(field) && StringUtils.isNotBlank(operator);
    }

    /**
     * 将前端条件转换为ES条件
     */
    private static JSONObject convertFrontendConditionToEs(JSONObject condition) {
        String field = condition.getString("field");
        String operator = condition.getString("operator");
        Object value = condition.get("value");
        
        if (value == null && !operator.equals("exists") && !operator.equals("not exists")) {
            return null;
        }

        String strValue = value != null ? value.toString() : "";
        JSONObject query = new JSONObject();

        switch (operator) {
            case ":":
            case "==":
                JSONObject matchPhrase = new JSONObject();
                matchPhrase.put(field, strValue);
                query.put("match_phrase", matchPhrase);
                break;

            case "*":
                JSONObject wildcard = new JSONObject();
                wildcard.put(field, "*" + strValue + "*");
                query.put("wildcard", wildcard);
                break;

            case "!=":
                JSONObject notMatchPhrase = new JSONObject();
                notMatchPhrase.put(field, strValue);
                JSONObject notBool = new JSONObject();
                notBool.put("must_not", Collections.singletonList(Collections.singletonMap("match_phrase", notMatchPhrase)));
                query.put("bool", notBool);
                break;

            case ">":
                JSONObject gtRange = new JSONObject();
                gtRange.put(field, Collections.singletonMap("gt", strValue));
                query.put("range", gtRange);
                break;

            case ">=":
                JSONObject gteRange = new JSONObject();
                gteRange.put(field, Collections.singletonMap("gte", strValue));
                query.put("range", gteRange);
                break;

            case "<":
                JSONObject ltRange = new JSONObject();
                ltRange.put(field, Collections.singletonMap("lt", strValue));
                query.put("range", ltRange);
                break;

            case "<=":
                JSONObject lteRange = new JSONObject();
                lteRange.put(field, Collections.singletonMap("lte", strValue));
                query.put("range", lteRange);
                break;

            case "contains":
                JSONObject contains = new JSONObject();
                contains.put(field, "*" + strValue + "*");
                query.put("wildcard", contains);
                break;

            case "not contains":
                JSONObject notContainsWildcard = new JSONObject();
                notContainsWildcard.put(field, "*" + strValue + "*");
                JSONObject notContainsBool = new JSONObject();
                notContainsBool.put("must_not", Collections.singletonList(Collections.singletonMap("wildcard", notContainsWildcard)));
                query.put("bool", notContainsBool);
                break;

            case "in":
                JSONObject terms = new JSONObject();
                if (value instanceof JSONArray) {
                    terms.put(field, value);
                } else {
                    terms.put(field, Collections.singletonList(strValue));
                }
                query.put("terms", terms);
                break;

            case "not in":
                JSONObject notInTerms = new JSONObject();
                if (value instanceof JSONArray) {
                    notInTerms.put(field, value);
                } else {
                    notInTerms.put(field, Collections.singletonList(strValue));
                }
                JSONObject notInBool = new JSONObject();
                notInBool.put("must_not", Collections.singletonList(Collections.singletonMap("terms", notInTerms)));
                query.put("bool", notInBool);
                break;

            case "exists":
                JSONObject exists = new JSONObject();
                exists.put("field", field);
                query.put("exists", exists);
                break;

            case "not exists":
                JSONObject notExistsExists = new JSONObject();
                notExistsExists.put("field", field);
                JSONObject notExistsBool = new JSONObject();
                notExistsBool.put("must_not", Collections.singletonList(Collections.singletonMap("exists", notExistsExists)));
                query.put("bool", notExistsBool);
                break;

            default:
                JSONObject match = new JSONObject();
                match.put(field, strValue);
                query.put("match", match);
                break;
        }

        return query;
    }

    /**
     * 转换单个条件
     */
    private static Map<String, Object> convertSingleCondition(JSONObject condition) {
        Map<String, Object> frontendCondition = new HashMap<>();

        if (condition.containsKey("match_phrase")) {
            // 精确匹配
            JSONObject matchPhrase = condition.getJSONObject("match_phrase");
            String field = matchPhrase.keySet().iterator().next();
            frontendCondition.put("field", field);
            frontendCondition.put("operator", ":");
            frontendCondition.put("value", matchPhrase.get(field));
        } else if (condition.containsKey("wildcard")) {
            // 通配符匹配
            JSONObject wildcard = condition.getJSONObject("wildcard");
            String field = wildcard.keySet().iterator().next();
            String value = wildcard.getString(field);
            frontendCondition.put("field", field);
            frontendCondition.put("operator", "*");
            frontendCondition.put("value", value.replaceAll("\\*", ""));
        } else if (condition.containsKey("range")) {
            // 范围查询
            JSONObject range = condition.getJSONObject("range");
            String field = range.keySet().iterator().next();
            JSONObject rangeOps = range.getJSONObject(field);
            frontendCondition.put("field", field);
            
            if (rangeOps.containsKey("gt")) {
                frontendCondition.put("operator", ">");
                frontendCondition.put("value", rangeOps.get("gt"));
            } else if (rangeOps.containsKey("gte")) {
                frontendCondition.put("operator", ">=");
                frontendCondition.put("value", rangeOps.get("gte"));
            } else if (rangeOps.containsKey("lt")) {
                frontendCondition.put("operator", "<");
                frontendCondition.put("value", rangeOps.get("lt"));
            } else if (rangeOps.containsKey("lte")) {
                frontendCondition.put("operator", "<=");
                frontendCondition.put("value", rangeOps.get("lte"));
            }
        } else if (condition.containsKey("terms")) {
            // terms查询 (in)
            JSONObject terms = condition.getJSONObject("terms");
            String field = terms.keySet().iterator().next();
            frontendCondition.put("field", field);
            frontendCondition.put("operator", "in");
            frontendCondition.put("value", terms.get(field));
        } else if (condition.containsKey("exists")) {
            // exists查询
            JSONObject exists = condition.getJSONObject("exists");
            frontendCondition.put("field", exists.getString("field"));
            frontendCondition.put("operator", "exists");
        } else if (condition.containsKey("match")) {
            // 普通匹配
            JSONObject match = condition.getJSONObject("match");
            String field = match.keySet().iterator().next();
            frontendCondition.put("field", field);
            frontendCondition.put("operator", "=");
            frontendCondition.put("value", match.get(field));
        }

        return frontendCondition;
    }
} 